/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.tom_roush.fontbox.cmap;

import junit.framework.TestCase;

/**
 * This will test the CodeSpaceRange implementation.
 *
 */
public class TestCodespaceRange extends TestCase
{

   /**
    * Check whether the code length calculation works.
    */
   public void testCodeLength()
   {
      byte[] startBytes1 = new byte[] { 0x00 };
      byte[] endBytes1 = new byte[] { 0x20 };
      CodespaceRange range1 = new CodespaceRange(startBytes1, endBytes1);
      assertEquals(1, range1.getCodeLength());

      byte[] startBytes2 = new byte[] { 0x00, 0x00 };
      byte[] endBytes2 = new byte[] { 0x01, 0x20 };
      CodespaceRange range2 = new CodespaceRange(startBytes2, endBytes2);
      assertEquals(2, range2.getCodeLength());
   }

   /**
    * Check whether the constructor checks the length of the start and end bytes
    */
   public void testConstructor()
   {
      // PDFBOX-4923 "1 begincodespacerange <00> <ffff> endcodespacerange" case is accepted
      byte[] startBytes1 = new byte[] { 0x00 };
      byte[] endBytes2 = new byte[] { -1, -1 };
      new CodespaceRange(startBytes1, endBytes2);

      // other cases of different lengths are not
      byte[] startBytes3 = new byte[] { 0x01 };
      byte[] endBytes4 = new byte[] { 0x01, 0x20 };
      try
      {
         new CodespaceRange(startBytes3, endBytes4);
         fail("The constructor should have thrown an IllegalArgumentException exception.");
      }
      catch (IllegalArgumentException exception)
      {
         // everything is fine as the expected exception is thrown
      }
   }

   public void testMatches()
   {
      byte[] startBytes1 = new byte[] { 0x00 };
      byte[] endBytes1 = new byte[] { (byte) 0xA0 };
      CodespaceRange range1 = new CodespaceRange(startBytes1, endBytes1);
      // check start and end value
      assertTrue(range1.matches(new byte[] { 0x00 }));
      assertTrue(range1.matches(new byte[] { (byte) 0xA0 }));
      // check any value within range
      assertTrue(range1.matches(new byte[] { 0x10 }));
      // check first value out of range
      assertFalse(range1.matches(new byte[] { (byte) 0xA1 }));
      // check any value out of range
      assertFalse(range1.matches(new byte[] { (byte) 0xD0 }));
      // check any value with a different code length
      assertFalse(range1.matches(new byte[] { 0x00, 0x10 }));

      byte[] startBytes2 = new byte[] { (byte) 0x81, 0x40 };
      byte[] endBytes2 = new byte[] { (byte) 0x9F, (byte) 0xFC };
      CodespaceRange range2 = new CodespaceRange(startBytes2, endBytes2);
      // check lower start and end value
      assertTrue(range2.matches(new byte[] { (byte) 0x81, 0x40 }));
      assertTrue(range2.matches(new byte[] { (byte) 0x81, (byte) 0xFC }));
      // check higher start and end value
      assertTrue(range2.matches(new byte[] { (byte) 0x81, 0x40 }));
      assertTrue(range2.matches(new byte[] { (byte) 0x9F, 0x40 }));
      // check any value within lower range
      assertTrue(range2.matches(new byte[] { (byte) 0x81, 0x65 }));
      // check any value within higher range
      assertTrue(range2.matches(new byte[] { (byte) 0x90, 0x40 }));
      // check first value out of lower range
      assertFalse(range2.matches(new byte[] { (byte) 0x81, (byte) 0xFD }));
      // check first value out of higher range
      assertFalse(range2.matches(new byte[] { (byte) 0xA0, 0x40 }));
      // check any value out of lower range
      assertFalse(range2.matches(new byte[] { (byte) 0x81, 0x20 }));
      // check any value out of higher range
      assertFalse(range2.matches(new byte[] { 0x10, 0x40 }));
      // check value between start and end but not within the rectangular
      assertFalse(range2.matches(new byte[] { (byte) 0x82, 0x20 }));
      // check any value with a different code length
      assertFalse(range2.matches(new byte[] { 0x00 }));
   }

}
